
//////// objectHandler.cpp ///////////////////////////////////////////////
//    Author:        Richard (richard.lindholm85@gmail.com)             //
//    Project:    some game project                                     //
//    Version:    0.1                                                   //
//    Purpose:    objectHandler class,                                  //
//                Handle for all objects, players, enemies, etc         //
//    Comments:    Maybe I should use K.I.S.S. (Keep It Simple Stupid)  //
//                more                                                  //
//////////////////////////////////////////////////////////////////////////

#include "objectHandler.h"




/// Set current object
/*bool cGameObject::setCurrentObject(string name)
{
    if (m_vObjList.size() == 0)
        return false;

    for (int i = 0; i < (int)m_vObjList.size(); i++)
    {
        if (m_vObjList[i]->name == name)
        {
            m_pCurrentObject = m_vObjList[i];
            return true;
        }
    }

    return false;
}*/

/// Set current object
/*bool cGameObject::setCurrentObject(OBJECT * obj)
{
    // also check if object exist in m_vObjList
    if (obj)
    {
        m_pCurrentObject = obj;
        return true;
    }

    return false;
}*/

/// Get current object
/*OBJECT * cGameObject::getObjectByName(string name)
{
    if (m_vObjList.size() == 0)
        return 0;

    for (int i = 0; i < (int)m_vObjList.size(); i++)
    {
        if (m_vObjList[i]->name == name)
        {
            return m_vObjList[i];
        }
    }
    return 0;
}*/

/// Get object by name
/*OBJECT * cGameObject::getObjectByName(const char * name)
{
    return getObjectByName(string(name));
}*/

/// Get object by at position[value]
/*OBJECT * cGameObject::getObjectAt(const int value)
{
    if (value > m_vObjList.size())
        return NULL;

    return m_vObjList[value];
}*/

;
cObjectHandler::cObjectHandler()
{
    m_pCurrentObject = NULL;
    m_pCurrentPlayer = NULL;
}

cObjectHandler::~cObjectHandler()
{
    if (m_ObjectList.size() > 0)
    {
        m_ObjectList.clear();
    }
    if (m_PlayerList.size() > 0)
    {
        m_PlayerList.clear();
    }
}

/// Object Functions ///
void cObjectHandler::newObject(INTPOINT pos, INTPOINT size, unsigned int type, string name)
{
    cGameObject * object = new cGameObject();

    object->setCollide(0);
    object->setType(type);
    object->setState(0);
    object->setPos(pos);
    object->setSize(size);
    object->setVelocity(0.0f, 0.0f);
    object->setName(name.c_str());

    m_ObjectList.push_back(object);
}
/* TODO: add some removeObject functions here later */

void cObjectHandler::updateObjects()
{
    if (m_ObjectList.size() == 0)
        return;

    for (int i = 0; i < (int)m_ObjectList.size(); i++)
    {
        for (int j = 0; j < (int)m_ObjectList.size(); j++)
        {
            m_ObjectList[i]->isCollidingWith(m_ObjectList[j]);
        }
        for (int j = 0; j < (int)m_PlayerList.size(); j++)
        {
            m_ObjectList[i]->isCollidingWith(m_PlayerList[j]);
        }
        //if (m_vObjList[i]->state == STATE_IDLE && m_vObjList[i]->type == TYPE_DYNAMIC)
        //{
        //    m_vObjList[i]->velocity.Y += 0.5f;
        //}
        if (m_ObjectList[i]->getType() == TYPE_DYNAMIC && m_ObjectList[i]->getCollide() == COLLIDE_NONE)
        {
            if (m_ObjectList[i]->getCollide() != COLLIDE_BOTTOM) m_ObjectList[i]->addVelocityY(0.5f);

            if (m_ObjectList[i]->getVelocity().X > 5.0f) m_ObjectList[i]->setVelocityX(5.0f);
            if (m_ObjectList[i]->getVelocity().Y > 5.0f) m_ObjectList[i]->setVelocityY(5.0f);

            m_ObjectList[i]->addPos((int)m_ObjectList[i]->getVelocity().X, (int)m_ObjectList[i]->getVelocity().Y);
            
            if (m_ObjectList[i]->getVelocity().X > 0) m_ObjectList[i]->addVelocityX(-1);
            if (m_ObjectList[i]->getVelocity().X < 0) m_ObjectList[i]->addVelocityX(1);
            //if (m_ObjectList[i]->velocity.Y > 0) m_ObjectList[i]->velocity.Y--; //there is gravity
            if (m_ObjectList[i]->getVelocity().Y < 0) m_ObjectList[i]->addVelocityY(1);
        }
    }
}

int cObjectHandler::getNumObjects()
{
    return m_ObjectList.size();
}

cGameObject * cObjectHandler::getObjectByName(const char * name)
{
    return getObjectByName(std::string(name));
}

cGameObject * cObjectHandler::getObjectByName(std::string name)
{
    if (m_ObjectList.size() == 0)
        return NULL;

    for (int i = 0; i < (int)m_ObjectList.size(); i++)
    {
        if (m_ObjectList[i]->getName() == name)
        {
            return m_ObjectList[i];
        }
    }

    return NULL;
}

cGameObject * cObjectHandler::getObjectAt(int value)
{
    if (m_ObjectList.size() == 0 || value > (int)m_ObjectList.size())
        return NULL;

    return m_ObjectList[value];
}

cGameObject * cObjectHandler::getCurrentObject()
{
    return m_pCurrentObject;
}

void cObjectHandler::setCurrentObject(cGameObject * obj)
{
    this->m_pCurrentObject = obj;
}

void cObjectHandler::setCurrentObject(std::string name)
{
    if (m_ObjectList.size() == 0)
        return;

    for (int i = 0; i < (int)m_ObjectList.size(); i++)
    {
        if (m_ObjectList[i]->getName() == name)
        {
            this->m_pCurrentObject = m_ObjectList[i];
        }
    }
}

void cObjectHandler::setCurrentObject(const char * name)
{
    setCurrentObject(std::string(name));
}


/// Player Functions ///
void cObjectHandler::newPlayer(int startX, int startY, int width, int height, std::string playerName)
{
    cPlayer * player = new cPlayer();

    player->setType(TYPE_DYNAMIC);
    player->setState(0);
    player->setCollide(0);
    player->setVelocity(0.0f, 0.0f);
    player->setPos(startX, startY);
    player->setSize(width, height);
    player->setHP(1000);
    player->setPlayerState(0);
    player->setName(playerName);

    m_PlayerList.push_back(player);
}
/* TODO: add some removePlayer functions here later */

void cObjectHandler::updatePlayers()
{
    if (m_PlayerList.size() == 0)
        return;

    for (int i = 0; i < (int)m_PlayerList.size(); i++)
    {
        for (int j = 0; j < (int)m_ObjectList.size(); j++)
        {
            m_PlayerList[i]->isCollidingWith(m_ObjectList[j]);
        }

        if (m_PlayerList[i]->getCollide() != COLLIDE_TOP)
        {
            m_PlayerList[i]->addPos((int)m_PlayerList[i]->getVelocity().X, (int)m_PlayerList[i]->getVelocity().Y);
            if (m_PlayerList[i]->getVelocity().Y < 5.0f)
            {
                m_PlayerList[i]->addVelocityY(0.5f);
            }
        }

        if (m_PlayerList[i]->getPlayerState() == PSTATE_RUNNING && m_PlayerList[i]->getCollide() == COLLIDE_NONE ||
            m_PlayerList[i]->getPlayerState() == PSTATE_JUMPING && m_PlayerList[i]->getCollide() == COLLIDE_NONE)
        {

            //if (m_PlayerList[i].second->pos.Y + m_PlayerList[i].second->size.Y > 450)
            //{
            //    m_PlayerList[i].second->pos.Y = 450 - m_PlayerList[i].second->size.Y;
            //    m_PlayerList[i].second->velocity.Y = 0.0f;
            //    m_PlayerList[i].second->collide = 1;
            //}
            //else m_PlayerList[i].second->collide = 0;
            
            if (m_PlayerList[i]->getVelocity().X > 0.0f) m_PlayerList[i]->addVelocityX(-1);
            else m_PlayerList[i]->addVelocityX(1);

            //if (m_PlayerList[i].second->velocity.Y < 0) m_PlayerList[i].second->velocity.Y--;
            //else m_PlayerList[i].second->velocity.Y++;

            //if (m_PlayerList[i]->getVelocity().X < 1.1f && m_PlayerList[i]->getVelocity().X > -1.1f)
            //    m_PlayerList[i]->setVelocityX(0.0f);
           // if (m_PlayerList[i]->getVelocity().Y < 1.1f && m_PlayerList[i]->getVelocity().Y > -1.1f)
            //    m_PlayerList[i]->setVelocityY(0.0f);
            if (m_PlayerList[i]->getVelocity().X == 0.0f && m_PlayerList[i]->getVelocity().Y == 0.0f && 
                m_PlayerList[i]->getPlayerState() != PSTATE_JUMPING)
            {
                m_PlayerList[i]->setPlayerState(PSTATE_IDLE);
                //m_PlayerList[i]->setCollide(1);
            }
        }
    }
}

int cObjectHandler::getNumPlayers()
{
    return m_PlayerList.size();
}

cPlayer * cObjectHandler::getPlayerByName(const char * name)
{
    return getPlayerByName(std::string(name));
}

cPlayer * cObjectHandler::getPlayerByName(std::string name)
{
    if (m_PlayerList.size() == 0)
        return NULL;

    for (int i = 0; i < (int)m_PlayerList.size(); i++)
    {
        if (m_PlayerList[i]->getName() == name)
        {
            return m_PlayerList[i];
        }
    }

    // if it cant be found, return null
    return NULL;
}

cPlayer * cObjectHandler::getPlayerAt(int value)
{
    if (m_PlayerList.size() == 0 || value > (int)m_PlayerList.size())
        return NULL;

    return m_PlayerList[value];
}


cPlayer * cObjectHandler::getCurrentPlayer()
{
    return m_pCurrentPlayer;
}

void cObjectHandler::setCurrentPlayer(cPlayer * player)
{
    this->m_pCurrentPlayer = player;
}

void cObjectHandler::setCurrentPlayer(std::string name)
{
    if (m_PlayerList.size() == 0)
        return;

    for (int i = 0; i < (int)m_PlayerList.size(); i++)
    {
        if (m_PlayerList[i]->getName() == name)
        {
            this->m_pCurrentPlayer = m_PlayerList[i];
        }
    }
}

void cObjectHandler::setCurrentPlayer(const char * name)
{
    setCurrentPlayer(std::string(name));
}

///
/// Function: isColliding(objA, objB)
/// Parameters: cGameObject * objA, cGameObject * objB
/// Purpose: test if objA and objB is colliding, return an integer over 0 if true
/// Return values: 0 = not colliding, 1 = top, 2 = bottom, 3 = left, 4 = right
/// TODO: always returns 1 if colliding at the moment, make it return the correct value at some time.
///
unsigned int cObjectHandler::isColliding(cGameObject * objA, cGameObject * objB)
{
    return m_pCurrentObject->isColliding(objA, objB);
}